package com.gin.ehdownloader.datafile;

import com.gin.aria2.utils.JsonUtils;
import com.gin.ehdownloader.entity.EhDownloadTask;
import com.gin.ehdownloader.utils.json.JsonDataFile;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 下载任务数据文件
 * @author : ginstone
 * @version : v1.0.0
 * @since : 2023/3/31 17:15
 */

public class TaskDataFile extends JsonDataFile<List<EhDownloadTask>> {
    public TaskDataFile(List<EhDownloadTask> data, File file) throws IOException {
        super(data, file, JsonUtils.MAPPER.getTypeFactory().constructCollectionLikeType(ArrayList.class, EhDownloadTask.class));
    }

    /**
     * 添加下载任务队列(尚未请求图片地址)
     * @param dir           下载目录
     * @param imagePageUrls 图片详情页地址
     */
    public void addTasks(String dir, Collection<String> imagePageUrls) throws IOException {
        data.addAll(imagePageUrls.stream().map(url -> new EhDownloadTask(dir, url)).toList());
        saveData();
    }

    /**
     * 清空指定任务的gid字段(重置任务状态，等待重新请求)
     * @param gid gid
     */
    public void clearGid(Collection<String> gid) throws IOException {
        data.stream().filter(t -> gid.contains(t.getGid())).forEach(t -> t.setGid(null));
        saveData();
    }

    /**
     * 返回一个尚未执行的下载任务
     * @return 任务
     */
    @Nullable
    public EhDownloadTask findTaskWithNullGid() {
        return data.stream().filter(i -> i.getGid() == null).findFirst().orElse(null);
    }

    /**
     * 返回所有gid
     * @return gid
     */
    public List<String> getGidList() {
        return data.stream().map(EhDownloadTask::getGid).filter(Objects::nonNull).collect(Collectors.toList());
    }

    /**
     * 添加任务成功时执行，将gid写入指定图片地址的任务
     * @param imagePageUrl 图片页面地址
     * @param gid          gid
     */
    public void onTaskAddSuccess(String imagePageUrl, String gid) throws IOException {
        final EhDownloadTask task = findTaskByImagePageUrl(imagePageUrl);
        if (task != null) {
            task.setGid(gid);
            saveData();
        }
    }

    /**
     * 任务下载完毕时执行，移除指定gid的任务
     * @param gid gid
     */
    public void onTaskCompleted(Collection<String> gid) throws IOException {
        data.removeIf(t -> gid.contains(t.getGid()));
        saveData();
    }

    /**
     * 更新gid
     * @param map 原gid到新gid的映射
     */
    public void updateGid(HashMap<String, String> map) throws IOException {
        map.forEach((o, n) -> {
            final EhDownloadTask task = findTaskByGid(o);
            if (task != null) {
                task.setGid(n);
            }
        });
        saveData();
    }

    @Nullable
    private EhDownloadTask findTaskByGid(String gid) {
        return data.stream().filter(t -> gid.equals(t.getGid())).findFirst().orElse(null);
    }

    @Nullable
    private EhDownloadTask findTaskByImagePageUrl(String imagePageUrl) {
        return data.stream().filter(t -> imagePageUrl.equals(t.getImagePageUrl())).findFirst().orElse(null);
    }
}
